home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / lineed.zip / ANSI.C < prev    next >
Text File  |  1992-04-05  |  20KB  |  848 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. /*
  6.  * to initialize:
  7.  *   call set_screensize(<# lines to reserve>);
  8.  * to print through ansi interpreter:
  9.  *   call ansi(<string>);
  10.  */
  11.  
  12. char               curattr = 7;
  13. int                curx = 0,cury = 0;
  14. int                topx = 0,topy = 0;     /* offset "down" to window */
  15. int                fakemaxx = 80, fakemaxy = 25;  /* size of ansi output window */
  16. int                maxy,maxx;             /* real screen size */
  17. char               useansi = 1;           /* while true, interp ansi seqs */
  18. int                tabspaces = 8;
  19. static int         savx,savy,issaved = 0;
  20. static char        ansi_terminators[] = "HFABCDnsuJKmp";
  21.  
  22. #ifdef __TURBOC__
  23.     #define _fastcall pascal
  24. #endif
  25.  
  26. #define MAXARGLEN       128
  27.  
  28. #define NOTHING         0
  29. #define WASESCAPE       1
  30. #define WASBRKT         2
  31.  
  32.  
  33. /* set fakemaxx,fakemaxy as desired */
  34. void _fastcall set_screensize (int reservedbotlines,int reservedtoplines);
  35.  
  36. /* put character c at x,y using attr as attribute */
  37. void _fastcall put_char (char c,char attr,int x,int y);
  38.  
  39. /* position hardware cursor at x,y */
  40. void _fastcall pos_hardcursor (int x,int y);
  41.  
  42. /* turn hardware cursor off */
  43. void _fastcall hardcursor_off (void);
  44.  
  45. /* turn hardware cursor on at x,y */
  46. void _fastcall hardcursor_on (int x,int y);
  47.  
  48. /* scroll window tx,ty - bx,by up one line; fill with blank+attr */
  49. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr);
  50.  
  51. /* clear the window from tx,ty - bx,by; fill with blank+attr */
  52. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr);
  53.  
  54. /* clear line y from col x to eol (ex); fill with blank+attr */
  55. void _fastcall cleartoeol (int x,int y,int ex,char attr);
  56.  
  57. /* validate cursor position after external routines may have changed it */
  58. void _fastcall validate_cursor (void);
  59.  
  60. /* get current cursor position */
  61. void _fastcall get_hardcursorpos (int *x,int *y);
  62.  
  63. /* printf replacement through ansi string interpreter */
  64. int aprintf(char *str,...);
  65.  
  66. /* the ansi string interpreter */
  67. int _fastcall ansi (char *buf);
  68.  
  69.  
  70.  
  71. /* "generic" support functions closely related to ansi */
  72.  
  73. void _fastcall set_pos (char *argbuf,int arglen,char cmd) {
  74.  
  75.     int   y,x;
  76.     char *p;
  77.  
  78.  
  79.     if(!*argbuf || !arglen) {
  80.         curx = topx;
  81.         cury = topy;
  82.     }
  83.     y = atoi(argbuf) - 1;
  84.     p = strchr(argbuf,';');
  85.     if(y >= 0 && p) {
  86.         x = atoi(p + 1) - 1;
  87.         if(x >= 0) {
  88.             curx = x;
  89.             cury = y;
  90.             curx += topx;
  91.             cury += topy;
  92.             if(curx > (fakemaxx + topx) - 1)
  93.               curx = (fakemaxx + topx) - 1;
  94.             if(cury > (fakemaxy + topy) - 1)
  95.               cury = (fakemaxy + topy) - 1;
  96.         }
  97.     }
  98. }
  99.  
  100.  
  101. void _fastcall go_up (char *argbuf,int arglen,char cmd) {
  102.  
  103.     int x;
  104.  
  105.     x = atoi(argbuf);
  106.     if(!x) x = 1;
  107.     for(;x;x--) {
  108.         if(cury <= topy) break;
  109.         cury--;
  110.     }
  111. }
  112.  
  113.  
  114. void _fastcall go_down (char *argbuf,int arglen,char cmd) {
  115.  
  116.     int x;
  117.  
  118.     x = atoi(argbuf);
  119.     if(!x) x = 1;
  120.     for(;x;x--) {
  121.         if(cury == (fakemaxy + topy) - 1) break;
  122.         cury++;
  123.     }
  124. }
  125.  
  126.  
  127. void _fastcall go_left (char *argbuf,int arglen,char cmd) {
  128.  
  129.     int x;
  130.  
  131.     x = atoi(argbuf);
  132.     if(!x) x = 1;
  133.     for(;x;x--) {
  134.         if(curx <= topx) break;
  135.         curx--;
  136.     }
  137. }
  138.  
  139.  
  140. void _fastcall go_right (char *argbuf,int arglen,char cmd) {
  141.  
  142.     int x;
  143.  
  144.     x = atoi(argbuf);
  145.     if(!x) x = 1;
  146.     for(;x;x--) {
  147.         if(curx == (fakemaxx + topx) - 1) break;
  148.         curx++;
  149.     }
  150. }
  151.  
  152.  
  153. void _fastcall report (char *argbuf,int arglen,char cmd) {
  154.  
  155.     /* you figure out how to implement it ... */
  156. }
  157.  
  158.  
  159. void _fastcall save_pos (char *argbuf,int arglen,char cmd) {
  160.  
  161.     savx = curx;
  162.     savy = cury;
  163.     issaved = 1;
  164. }
  165.  
  166.  
  167. void _fastcall restore_pos (char *argbuf,int arglen,char cmd) {
  168.  
  169.     if(issaved) {
  170.         curx = savx;
  171.         cury = savy;
  172.         issaved = 0;
  173.     }
  174. }
  175.  
  176.  
  177. void _fastcall clear_screen (char *argbuf,int arglen,char cmd) {
  178.  
  179.     /* needs error checking */
  180.  
  181.     clearwindow(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
  182.     curx = topx;
  183.     cury = topy;
  184. }
  185.  
  186.  
  187. void _fastcall kill_line (char *argbuf,int arglen,char cmd) {
  188.  
  189.     cleartoeol(curx + topx,cury + topy,(fakemaxx + topx) - 1,curattr);
  190. }
  191.  
  192.  
  193. void _fastcall set_ansicolors (char *argbuf,int arglen,char cmd) {
  194.  
  195.     char *p,*pp;
  196.  
  197.  
  198.     if(*argbuf && arglen) {
  199.         pp = argbuf;
  200.         do {
  201.             p = strchr(pp,';');
  202.             if(p && *p) {
  203.                 *p = 0;
  204.                 p++;
  205.             }
  206.             switch(atoi(pp)) {
  207.                 case 0: /* all attributes off */
  208.                     curattr = 7;
  209.                     break;
  210.  
  211.                 case 1: /* bright on */
  212.                     curattr |= 8;
  213.                     break;
  214.  
  215.                 case 2: /* faint on */
  216.                     curattr &= (~8);
  217.                     break;
  218.  
  219.                 case 3: /* italic on */
  220.                     break;
  221.  
  222.                 case 5: /* blink on */
  223.                     curattr |= 128;
  224.                     break;
  225.  
  226.                 case 6: /* rapid blink on */
  227.                     break;
  228.  
  229.                 case 7: /* reverse video on */
  230.                     curattr = 112;
  231.                     break;
  232.  
  233.                 case 8: /* concealed on */
  234.                     curattr = 0;
  235.                     break;
  236.  
  237.                 case 30: /* black fg */
  238.                     curattr &= (~7);
  239.                     break;
  240.  
  241.                 case 31: /* red fg */
  242.                     curattr &= (~7);
  243.                     curattr |= 4;
  244.                     break;
  245.  
  246.                 case 32: /* green fg */
  247.                     curattr &= (~7);
  248.                     curattr |= 2;
  249.                     break;
  250.  
  251.                 case 33: /* yellow fg */
  252.                     curattr &= (~7);
  253.                     curattr |= 6;
  254.                     break;
  255.  
  256.                 case 34: /* blue fg */
  257.                     curattr &= (~7);
  258.                     curattr |= 1;
  259.                     break;
  260.  
  261.                 case 35: /* magenta fg */
  262.                     curattr &= (~7);
  263.                     curattr |= 5;
  264.                     break;
  265.  
  266.                 case 36: /* cyan fg */
  267.                     curattr &= (~7);
  268.                     curattr |= 3;
  269.                     break;
  270.  
  271.                 case 37: /* white fg */
  272.                     curattr |= 7;
  273.                     break;
  274.  
  275.                 case 40: /* black bg */
  276.                     curattr &= (~112);
  277.                     break;
  278.  
  279.                 case 41: /* red bg */
  280.                     curattr &= (~112);
  281.                     curattr |= (4 << 4);
  282.                     break;
  283.  
  284.                 case 42: /* green bg */
  285.                     curattr &= (~112);
  286.                     curattr |= (2 << 4);
  287.                     break;
  288.  
  289.                 case 43: /* yellow bg */
  290.                     curattr &= (~112);
  291.                     curattr |= (6 << 4);
  292.                     break;
  293.  
  294.                 case 44: /* blue bg */
  295.                     curattr &= (~112);
  296.                     curattr |= (1 << 4);
  297.                     break;
  298.  
  299.                 case 45: /* magenta bg */
  300.                     curattr &= (~112);
  301.                     curattr |= (5 << 4);
  302.                     break;
  303.  
  304.                 case 46: /* cyan bg */
  305.                     curattr &= (~112);
  306.                     curattr |= (3 << 4);
  307.                     break;
  308.  
  309.                 case 47: /* white bg */
  310.                     curattr |= 112;
  311.                     break;
  312.  
  313.                 case 48: /* subscript bg */
  314.                     break;
  315.  
  316.                 case 49: /* superscript bg */
  317.                     break;
  318.  
  319.                 default: /* unsupported */
  320.                     break;
  321.             }
  322.             pp = p;
  323.         } while(p);
  324.     }
  325. }
  326.  
  327.  
  328. int aprintf (char *str,...) {
  329.  
  330.   va_list         ap;
  331.   static char     buffer[513];
  332.  
  333.   va_start (ap, str);
  334.   vsprintf (buffer, str, ap);
  335.   va_end (ap);
  336.  
  337.   return ansi(buffer);
  338. }
  339.  
  340.  
  341.  
  342. int _fastcall ansi (char *buf) {
  343.  
  344.     int  arglen = 0,ansistate = NOTHING,x;
  345.     char *b = buf,argbuf[MAXARGLEN] = "";
  346.  
  347.  
  348.     {   /* match our pos to hardware cursor's pos */
  349.       get_hardcursorpos(&curx,&cury);
  350.       if(curx > (fakemaxx + topx) - 1)
  351.         curx = (fakemaxx + topx) - 1;
  352.       if(cury > (fakemaxy + topy) - 1)
  353.         cury = (fakemaxy + topy) - 1;
  354.     }
  355.  
  356.     hardcursor_off();
  357.  
  358.     if(!useansi) {          /* is ANSI interp on? */
  359.       ansistate = NOTHING;
  360.       arglen = 0;
  361.       *argbuf = 0;
  362.     }
  363.  
  364.     while(*b) {
  365.         switch(ansistate) {
  366.           case NOTHING:
  367.                 switch(*b) {
  368.                     case '\x1b':
  369.                         if(useansi) {
  370.                           ansistate = WASESCAPE;
  371.                           break;
  372.                         }
  373.  
  374.                     case '\r':    /* C-like inp of \n (and \r) sorta */
  375.                     /* curx = topx;
  376.                        break; */
  377.  
  378.                     case '\n':
  379.                         curx = topx;
  380.                         cury++;
  381.                         if(cury > (fakemaxy + topy) - 1) {
  382.                             scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
  383.                             cury--;
  384.                         }
  385.                         break;
  386.  
  387.                     case '\t':     /* so _you_ figure out what to do... */
  388.                         for(x = 0;x < tabspaces;x++) {
  389.                             put_char(' ',curattr,curx + topx,cury + topy);
  390.                             curx++;
  391.                             if(curx > (fakemaxx + topx) - 1) {
  392.                                 curx = topx;
  393.                                 cury++;
  394.                                 if(cury > fakemaxy - 1) {
  395.                                     scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
  396.                                     cury--;
  397.                                 }
  398.                             }
  399.                         }
  400.                         break;
  401.  
  402.                     case '\b':
  403.                         if(curx > topx) {
  404.                             curx--;
  405.                         }
  406.                         break;
  407.  
  408.                     case '\07':     /* usually a console bell */
  409.                         putchar('\07');
  410.                         break;
  411.  
  412.                     default:
  413.                         put_char(*b,curattr,curx + topx,cury + topy);
  414.                         curx++;
  415.                         if(curx > (fakemaxx + topx) - 1) {
  416.                             curx = topx;
  417.                             cury++;
  418.                             if(cury > fakemaxy - 1) {
  419.                                 scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
  420.                                 cury--;
  421.                             }
  422.                         }
  423.                         break;
  424.                 }
  425.                 break;
  426.  
  427.           case WASESCAPE:
  428.             if(*b == '[') {
  429.                 ansistate = WASBRKT;
  430.                 arglen = 0;
  431.                 *argbuf = 0;
  432.                 break;
  433.             }
  434.             ansistate = NOTHING;
  435.             break;
  436.  
  437.           case WASBRKT:
  438.             if(strchr(ansi_terminators,(int)*b)) {
  439.                 switch((int)*b) {
  440.                     case 'H':   /* set cursor position */
  441.                     case 'F':
  442.                         set_pos(argbuf,arglen,*b);
  443.                         break;
  444.  
  445.                     case 'A':   /* up */
  446.                         go_up(argbuf,arglen,*b);
  447.                         break;
  448.  
  449.                     case 'B':   /* down */
  450.                         go_down(argbuf,arglen,*b);
  451.                         break;
  452.  
  453.                     case 'C':   /* right */
  454.                         go_right(argbuf,arglen,*b);
  455.                         break;
  456.  
  457.                     case 'D':   /* left */
  458.                         go_left(argbuf,arglen,*b);
  459.                         break;
  460.  
  461.                     case 'n':   /* report pos */
  462.                         report(argbuf,arglen,*b);
  463.                         break;
  464.  
  465.                     case 's':   /* save pos */
  466.                         save_pos(argbuf,arglen,*b);
  467.                         break;
  468.  
  469.                     case 'u':   /* restore pos */
  470.                         restore_pos(argbuf,arglen,*b);
  471.                         break;
  472.  
  473.                     case 'J':   /* clear screen */
  474.                         clear_screen(argbuf,arglen,*b);
  475.                         break;
  476.  
  477.                     case 'K':   /* delete to eol */
  478.                         kill_line(argbuf,arglen,*b);
  479.                         break;
  480.  
  481.                     case 'm':   /* set video attribs */
  482.                         set_ansicolors(argbuf,arglen,*b);
  483.                         break;
  484.  
  485.                     case 'p':   /* keyboard redef -- disallowed */
  486.                         break;
  487.  
  488.                     default:    /* unsupported */
  489.                         break;
  490.                 }
  491.                 ansistate = NOTHING;
  492.                 arglen = 0;
  493.                 *argbuf = 0;
  494.             }
  495.             else {
  496.                 if(arglen < MAXARGLEN) {
  497.                     argbuf[arglen] = *b;
  498.                     argbuf[arglen + 1] = 0;
  499.                     arglen++;
  500.                 }
  501.             }
  502.             break;
  503.  
  504.           default:
  505.             pos_hardcursor(curx + topx,cury + topy);
  506.             fputs("\n **Error in ANSI state machine.\n",stderr);
  507.             break;
  508.         }
  509.  
  510.         b++;
  511.     }
  512.  
  513.     pos_hardcursor(curx + topx,cury + topy);
  514.     hardcursor_on(curx + topx,cury + topy);
  515.  
  516.     return ((int)b - (int)buf);
  517. }
  518.  
  519.  
  520.  
  521. /* OS specific functions -- this can be moved to a separate module */
  522.  
  523. #ifdef OS2
  524.  
  525. #define INCL_DOS
  526. #define INCL_VIO
  527.  
  528. #include <os2.h>
  529.  
  530. int vidhandle = 0;  /* can be changed for AVIO */
  531.  
  532.  
  533. void _fastcall set_screensize (int reservedbotlines,int reservedtoplines) {
  534.  
  535.     VIOMODEINFO vm;
  536.  
  537.     vm.cb = sizeof(VIOMODEINFO);
  538.     VioGetMode(&vm, vidhandle);
  539.     fakemaxx = vm.col;
  540.     fakemaxy = vm.row - reservedbotlines;
  541.     topy = reservedtoplines;
  542.     fakemaxy -= topy;
  543.     maxx = fakemaxx;
  544.     maxy = vm.row;
  545. }
  546.  
  547.  
  548. void _fastcall pos_hardcursor (int x,int y) {
  549.  
  550.     VioSetCurPos(y,x,vidhandle);
  551. }
  552.  
  553.  
  554. void _fastcall hardcursor_off (void) {
  555.  
  556.     VIOCURSORINFO vc;
  557.  
  558.     VioGetCurType(&vc,vidhandle);
  559.     vc.attr = -1;
  560.     VioSetCurType(&vc,vidhandle);
  561. }
  562.  
  563.  
  564. void _fastcall hardcursor_on (int x,int y) {
  565.  
  566.     VIOCURSORINFO vc;
  567.  
  568.     VioGetCurType(&vc,vidhandle);
  569.     vc.attr = 0;
  570.     VioSetCurType(&vc,vidhandle);
  571.     VioSetCurPos(y,x,vidhandle);
  572. }
  573.  
  574.  
  575. void _fastcall put_char (char c, char attr, int x, int y) {
  576.  
  577.     VioWrtCharStrAtt(&c,1,y,x,&attr,vidhandle);
  578. }
  579.  
  580.  
  581. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
  582.  
  583.     int attrib = ' ' | (attr << 8);
  584.  
  585.     VioScrollUp(ty,tx,by,bx,1,(char *)&attrib,vidhandle);
  586. }
  587.  
  588.  
  589. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
  590.  
  591.     int attrib = ' ' | (attr << 8);
  592.  
  593.     VioScrollUp(ty,tx,by,bx,-1,(char *)&attrib,vidhandle);
  594. }
  595.  
  596.  
  597. void _fastcall cleartoeol (int x,int y,int ex,char attr) {
  598.  
  599.     int attrib = ' ' | (attr << 8);
  600.  
  601.     VioScrollUp(y,x,y,ex,-1,(char *)&attrib,vidhandle);
  602. }
  603.  
  604. void _fastcall validate_cursor (void) {
  605.  
  606.   int x,y;
  607.  
  608.   VioGetCurPos(&y,&x,vidhandle);
  609.   if(y > fakemaxy - 1) {
  610.     cury = fakemaxy - 1;
  611.   }
  612.   else cury = y;
  613.   curx = x;
  614. }
  615.  
  616. void _fastcall get_hardcursorpos (int *x,int *y) {
  617.  
  618.   VioGetCurPos(y,x,vidhandle);
  619. }
  620.  
  621. #else
  622.  
  623. /* MS-DOS -- this stuff has _not_ been tested */
  624.  
  625. #include <dos.h>
  626.  
  627. #if !defined(MK_FP)
  628.  #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
  629. #endif
  630.  
  631. static int far *vseg;
  632. int            maxy,maxx;
  633. char           usebios = 0; /* if true, output through BIOS */
  634.  
  635.  
  636. int _fastcall vmode (void) {
  637.  
  638.     union REGS r;
  639.  
  640.     r.h.ah = 15;
  641.     r.x.bx = 0;
  642.     int86(0x10,&r,&r);
  643.     return r.h.al;
  644. }
  645.  
  646.  
  647. void _fastcall set_screensize (int reservedbotlines,int reservedtoplines) {
  648.  
  649.     union REGS   r;
  650.     unsigned int vbase;
  651.  
  652.     r.h.ah = 0x0f;
  653.     r.x.bx = 0;
  654.     int86 (0x10, &r, &r);
  655.     fakemaxx = (int) r.h.ah;
  656.     if(fakemaxx < 80) {               /* gimme a break! */
  657.         r.x.ax = 0x0003;
  658.         int86(0x10,&r,&r);
  659.         fakemaxx = 80;
  660.     }
  661.     maxx = fakemaxx;
  662.     r.x.ax = 0x1130;
  663.     r.x.dx = fakemaxy;
  664.     int86 (0x10, &r, &r);
  665.     maxy = fakemaxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
  666.     fakemaxy -= reservedbotlines;
  667.  
  668.     topy = reservedtoplines;
  669.     fakemaxy -= topy;
  670.  
  671.     vbase = (vmode () == 7 ? 0xb000 : 0xb800);
  672.     vseg = MK_FP(vbase,0);       /* address of video ram as pointer */
  673. }
  674.  
  675.  
  676. void _fastcall pos_hardcursor (int x,int y) {
  677.  
  678.     union REGS r;
  679.  
  680.     r.x.ax = 0x0200;
  681.     r.x.bx = 0;
  682.     r.x.dx = ((y << 8) & 0xff00) + x;
  683.     int86(0x10,&r,&r);
  684. }
  685.  
  686.  
  687. void _fastcall hardcursor_off (void) {
  688.  
  689.     union REGS r;
  690.  
  691.     r.x.ax = 0x0200;
  692.     r.x.bx = 0;
  693.     r.x.dx = ((maxy << 8) & 0xff00);
  694.     int86(0x10,&r,&r);
  695. }
  696.  
  697.  
  698. void _fastcall hardcursor_on (int x,int y) {
  699.  
  700.     union REGS r;
  701.  
  702.     r.x.ax = 0x0200;
  703.     r.x.bx = 0;
  704.     r.x.dx = ((y << 8) & 0xff00) + x;
  705.     int86(0x10,&r,&r);
  706. }
  707.  
  708.  
  709. void _fastcall put_char (char c, char attr, int x, int y) {
  710.  
  711.   if(!usebios) {
  712.  
  713.     register int far *v;
  714.  
  715.     v = vseg + ((y * maxx) + x); /* point v to right spot in vid RAM */
  716.     *v = (c | (attr << 8));          /* display */
  717.   }
  718.   else {
  719.  
  720.     union REGS r;
  721.  
  722.     r.x.ax = 0x0200;
  723.     r.x.bx = 0;
  724.     r.x.dx = ((y << 8) & 0xff00) + x;
  725.     int86(0x10,&r,&r);
  726.     r.h.ah = 0x09;
  727.     r.h.bh = 0;
  728.     r.h.bl = attr;
  729.     r.x.cx = 1;
  730.     r.h.al = c;
  731.     int86(0x10,&r,&r);
  732.   }
  733. }
  734.  
  735.  
  736. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
  737.  
  738.     union REGS r;
  739.  
  740.     r.h.ah = 6;
  741.     r.h.al = 1;
  742.     r.h.bh = attr;
  743.     r.h.cl = tx;
  744.     r.h.ch = ty;
  745.     r.h.dl = bx;
  746.     r.h.dh = by;
  747.     int86(0x10,&r,&r);
  748. }
  749.  
  750.  
  751. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
  752.  
  753.     union REGS r;
  754.  
  755.     r.h.ah = 6;
  756.     r.h.al = 0;
  757.     r.h.bh = attr;
  758.     r.h.cl = tx;
  759.     r.h.ch = ty;
  760.     r.h.dl = bx;
  761.     r.h.dh = by;
  762.     int86(0x10,&r,&r);
  763. }
  764.  
  765.  
  766. void _fastcall cleartoeol (int x,int y,int ex,char attr) {
  767.  
  768.     union REGS r;
  769.  
  770.     r.h.ah = 6;
  771.     r.h.al = 0;
  772.     r.h.bh = attr;
  773.     r.h.cl = x;
  774.     r.h.ch = y;
  775.     r.h.dl = ex;
  776.     r.h.dh = y;
  777.     int86(0x10,&r,&r);
  778. }
  779.  
  780.  
  781. void _fastcall validate_cursor (void) {
  782.  
  783.   union REGS r;
  784.  
  785.   r.x.ax = 0x0300;
  786.   r.x.bx = 0;
  787.   int86(0x10,&r,&r);
  788.   if(r.h.dh > fakemaxy - 1) {
  789.     cury = fakemaxy - 1;
  790.   }
  791.   else cury = (int)r.h.dh;
  792.   curx = (int)r.h.dl;
  793. }
  794.  
  795. int _fastcall dputs (int x,int y,char attr,char *s) {
  796.  
  797.   int oldx,oldy;
  798.   char *p;
  799.   union REGS r;
  800.  
  801.   if(s && s) {
  802.     r.x.ax = 0x0300;
  803.     r.x.bx = 0;
  804.     int86(0x10,&r,&r);
  805.     oldx = r.h.dl;
  806.     oldy = r.h.dh;
  807.     p = s;
  808.     while(*p) {
  809.       put_char(*p,attr,x,y);
  810.       x++;
  811.       p++;
  812.     }
  813.     r.x.ax = 0x0200;
  814.     r.x.bx = 0;
  815.     r.x.dx = ((oldy << 8) & 0xff00) + oldx;
  816.     int86(0x10,&r,&r);
  817.   }
  818.   return ((int)p - (int)s);
  819. }
  820.  
  821.  
  822. int dprintf (int x,int y,char attr,char *str,...) {
  823.  
  824.   va_list         ap;
  825.   static char     buffer[318];
  826.  
  827.   va_start (ap, str);
  828.   vsprintf (buffer, str, ap);
  829.   va_end (ap);
  830.  
  831.   return dputs(x,y,attr,buffer);
  832. }
  833.  
  834.  
  835.  
  836. void _fastcall get_hardcursorpos (int *x,int *y) {
  837.  
  838.   union REGS r;
  839.  
  840.   r.x.ax = 0x0300;
  841.   r.x.bx = 0;
  842.   int86(0x10,&r,&r);
  843.   *x = r.h.dl;
  844.   *y = r.h.dh;
  845. }
  846.  
  847. #endif
  848.